package org.wattdepot.simulation.oahugrid.powerplant;

import static org.wattdepot.simulation.oahugrid.powerplant.PowerPlant.*;
import java.util.ArrayList;
import java.util.List;

/**
 * Provides a subset of all PowerPlants to be used for power generation. Note that ordering is
 * important; the plants will be used in the order in which they appear given their PeakType.
 * Generally, the plants are ordered: Baseload, Cycling, Peaking, although that is not necessary.
 * 
 * @author Philip Johnson
 */
public enum PowerPlantSet {
  /** A plant set that prefers low carbon emitting plants. */
  LOW_CARBON_PLANTS(SIM_HPOWER, SIM_KAHE_6, SIM_KAHE_5, SIM_KAHE_4, SIM_KAHE_3, SIM_KAHE_2,
      SIM_KAHE_1, SIM_KALAELOA, SIM_WAIAU_5, SIM_WAIAU_6, SIM_HONOLULU_8, SIM_HONOLULU_9,
      SIM_WAIAU_9, SIM_WAIAU_10, SIM_WAIAU_7, SIM_WAIAU_8, SIM_AES, SIM_KAHE_7),
  /** A plant set that prefers high carbon emitting plants. */
  HIGH_CARBON_PLANTS(SIM_AES, SIM_KALAELOA, SIM_WAIAU_7, SIM_WAIAU_8, SIM_KAHE_6, SIM_KAHE_5,
      SIM_KAHE_4, SIM_KAHE_3, SIM_KAHE_2, SIM_KAHE_1, SIM_HONOLULU_8, SIM_HONOLULU_9, SIM_WAIAU_5,
      SIM_WAIAU_6, SIM_WAIAU_9, SIM_WAIAU_10, SIM_KAHE_7, SIM_HPOWER);

  /** Holds the set of plants specified in the constructor. */
  private PowerPlant[] plants;

  /**
   * Takes an ordered list of PowerPlants.
   * This list must include all defined PowerPlants.
   * 
   * @param plants The plants to be used, in order.
   */
  private PowerPlantSet(PowerPlant... plants) {
    this.plants = plants;
    if (this.plants.length != PowerPlant.values().length) {
      throw new RuntimeException("PowerPlantSet does not include all defined Power Plants.");
    }
  }

  /**
   * Returns the plants of a given type in their original order.
   * 
   * @param type The PowerPlant type.
   * @return A list of plants of that type, in order by their preference of usage.
   */
  public List<PowerPlant> getPlants(Type type) {
    List<PowerPlant> typedPlants = new ArrayList<PowerPlant>();
    for (PowerPlant plant : plants) {
      if (plant.getType() == type) {
        typedPlants.add(plant);
      }
    }
    return typedPlants;
  }

  /**
   * Returns the maximum MW available by this set of power plants for the grid.
   * 
   * @return The maximum MW available.
   */
  public int getCapacity() {
    int capacity = 0;
    for (PowerPlant plant : plants) {
      capacity += plant.getMaxMW();
    }
    return capacity;
  }

}
